
import random
import re
from datetime import datetime

from flask import abort, jsonify
from flask import current_app
from flask import make_response
from flask import request
from flask import session

from info import constants, db
from info import redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.response_code import RET
from . import passport_blu
from info.utils.captcha.captcha import captcha

@passport_blu.route("/login",methods=["POST"])
def login():
    # 1 获取参数 2  校验参数 3校验密码 保存用户登陆状态 5 响应
    params_dict=request.json
    mobile=params_dict.get("mobile")
    password=params_dict.get("password")

    #2  校验参数
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数有误")

    if not re.match("1[35678]\\d{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号码输入错误")

    try:
        user=User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        return  jsonify(errno=RET.DBERR,errmsg="数据查询错误")

    if not user:
        return jsonify(errno=RET.NODATA,errmsg="用户不存在")

    # 校验密码
    if not user.check_password(password):
        return jsonify(errno=RET.PWDERR,errmsg="用户名或密码错误")

    # 4,保存用户的登陆状态
    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile
    # 记录最新登陆时间
    user.last_login = datetime.now()
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)

    return jsonify(errno=RET.OK,errmsg="登陆成功")


@passport_blu.route("/register",methods=["POST"])
def register():
    """
    1.获取参数
    2.校验参数
    3.取到服务器保存的验证码
    4 校验 验证码是否一直
    5 如果一致 ，初始化user模型，并且属性
    6 保存user模型
    7 返回结果
    """
    params_dict = request.json
    mobile = params_dict.get("mobile")
    smscode = params_dict.get("smscode")
    password= params_dict.get("password")
    #2. 校验参数是否有值  if not all([])
    if not all([mobile,smscode,password]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数有误")

    if not re.match("1[35678]\\d{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号码输入错误")
    #3.取到服务器保存的验证码并且校验
    try:
        real_sms_code=redis_store.get("SMS" + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据查询失败")

    if not real_sms_code:
        return jsonify(errno=RET.DATAERR,errmsg="验证码错误")

    if real_sms_code != smscode:
        # print(type(smscode))
        # print(type(real_sms_code))
        current_app.logger.debug("手机验证码是：%s"%smscode)
        current_app.logger.debug("手机收到的码是：%s"%real_sms_code)
        return jsonify(errno=RET.DATAERR,errmsg="验证错误")

    user=User()
    user.mobile=mobile
    user.nick_name=mobile
    user.last_login=datetime.now()
    #加密password，使用hash
    user.password=password


    #添加到数据库
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg="数据保存失败")

    #保存注册成功后的登陆状态
    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile

    # 6. 返回注册结果
    return jsonify(errno=RET.OK, errmsg="注册成功")


@passport_blu.route('/image_code')
def get_image_code():
    """
    生成图片验证码并返回
    1 取到参数
    2 判断参数是否优质
    3 生成图片验证码
    4 保存图片验证码到redis
     5返回验证码图片
    """
    #从request渠道设置的参数ImageCodeId
    image_code_id=request.args.get("imageCodeId",None)
    #判断参数是否有值

    if not image_code_id:
        return abort(403)

    name,text,image=captcha.generate_captcha()
    #captcha包生成一个图片，名字，和内容
    current_app.logger.debug("图片验证码内容是%s"%text)
    try:
        redis_store.set("ImageCode"+image_code_id,text,constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        abort(500)



    response=make_response(image)
    response.headers['Content-Type'] = 'image/jpg'
    return response

@passport_blu.route("/sms_code",methods=["POST"])
def send_sms_code():
    """
    1,获取参数，手机号，段兴验证码内容，图片验证码的编号
    2，校验参数，判断是否有值，是否符合规则
    3，先从erdis中取出真是的验证码内容
    4，与用户的验证码内容对比是否一直
    5如果一直，生成验证码内容
    6，发送段兴验证码
    7 告知发送结果
    :return:
    """

    # 1, 获取参数，手机号，段兴验证码内容，图片验证码的编号
    params_dict=request.json
    mobile=params_dict.get("mobile")
    image_code=params_dict.get("image_code")
    image_code_id=params_dict.get("image_code_id")
    #2 判断是否有值
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数有误")
    # 3，先从erdis中取出真是的验证码内容
    if not re.match("1[35678]\\d{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg="手机号码输入错误")

    try:
        real_image_code=redis_store.get("ImageCode"+image_code_id)
    except Exception as e:
        return jsonify(errno=RET.PARAMERR, errmsg="数据查询失败")

    if not real_image_code:
        return jsonify(errno=RET.PARAMERR, errmsg="验证码已失效")

    if image_code.upper() != real_image_code.upper():
        return jsonify(errno=RET.DATAERR, errmsg="验证码输入有误")


    sms_code_str="%06d"%random.randint(0,999999)
    current_app.logger.debug("短信验证码内容：%s"%sms_code_str)


    # result= CCP().send_template_sms(mobile,[sms_code_str,constants.SMS_CODE_REDIS_EXPIRES],"1")
    # if result !=0:
    #     return jsonify(errno=RET.THIRDERR,errmsg="发送短信失败")

    # 生成短信验证码，并且保存在redis里
    try:
        redis_store.set("SMS" + mobile, sms_code_str,constants.IMAGE_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="数据保存失败")


    return jsonify(errno=RET.OK,errmsg="发送短信成功")


@passport_blu.route("/logout")
def logout():
    #pop 是移除session中的数据
    #用pop是因为有返回值，一出之后会返回第二个参数none
    session.pop("user_id",None)
    session.pop("mobile",None)
    session.pop("nick_name",None)

    return jsonify(errno=RET.OK,errmsg="退出成功")